package island.gotenyama.wand.validation;

import island.gotenyama.wand.annotation.FieldDefinition;
import island.gotenyama.wand.annotation.Length;
import island.gotenyama.wand.bean.AField;
import island.gotenyama.wand.bean.MessageKey;
import island.gotenyama.wand.exception.FatalException;

import org.springframework.stereotype.Component;

/**
 * を検証する。
 * 
 * @author tkawabata
 */
@Component
public class LengthValidation extends AValidation {

	/**
	 * エラーコード
	 */
	public static final String errorCode = "input.error.length";

	public static final String errorCodeMin = "input.error.lengthMin";
	
	public static final String errorCodeMax = "input.error.lengthMax";
	
	public static final String errorCodeMinMax = "input.error.lengthMinMax";
	
	@Override
	public boolean isValid(Object entry, Object... params) {
		if (entry == null) {
			return true;
		}
		if (params == null || params.length < 2) {
			throw new FatalException("Length is Null.");
		}
		int len = entry.toString().length();
		Integer min = (Integer) params[0];
		Integer max = (Integer) params[1];
		if (min > 0) {
			if (len < min) {
				return false;
			}
		}
		if (max > 0) {
			if (len > max) {
				return false;
			}
		}
		return true;
	}

	@Override
	public MessageKey validate(AField aField, Object entry) {
		if (aField == null) {
			throw new FatalException("NULLのため、検証できない。");
		}
		Length length = aField.getField().getAnnotation(Length.class);
		Integer min = length.min();
		Integer max = length.max();
		if (isValid(entry, min, max)) {
			return null;
		} else {
			FieldDefinition fieldDef = aField.getFieldDefinition();
			String code = null;
			if (min == max) {
				code = errorCode;
				return new MessageKey(code, fieldDef.name(), fieldDef.nameJp(), min.toString());
			} else if (min < 1) {
				code = errorCodeMax;
				return new MessageKey(code, fieldDef.name(), fieldDef.nameJp(), min.toString());
			} else if (max < 1) {
				code = errorCodeMin;
				return new MessageKey(code, fieldDef.name(), fieldDef.nameJp(), max.toString());
			} else  {
				code = errorCodeMinMax;
				return new MessageKey(code, fieldDef.name(), fieldDef.nameJp(), min.toString(), max.toString());
			}
		}
	}
}
